package cn.shujuhai.common.config;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.safety.Safelist;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: NiuYaHu
 * @Date: 2025/5/14 14:56
 * @Description:
 **/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    // 定义一个基本的白名单，允许一些基本的HTML标签和属性
    private static final Safelist safelist = Safelist.basicWithImages();
    private static final Document.OutputSettings outputSettings = new Document.OutputSettings().prettyPrint(false);

    // 构造函数，传入原始的HttpServletRequest
    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    // 重写getParameter方法，对每个请求参数进行XSS过滤
    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name); // 获取原始参数值
        return clean(value); // 对参数值进行XSS过滤
    }

    // 重写getParameterMap方法，对所有请求参数进行XSS过滤
    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> map = new HashMap<>();
        Map<String, String[]> originalMap = super.getParameterMap(); // 获取原始参数映射
        for (Map.Entry<String, String[]> entry : originalMap.entrySet()) {
            String[] values = entry.getValue(); // 获取原始参数值数组
            String[] cleanValues = new String[values.length]; // 创建一个相同长度的数组用于存储过滤后的值
            for (int i = 0; i < values.length; i++) {
                cleanValues[i] = clean(values[i]); // 对每个参数值进行XSS过滤
            }
            map.put(entry.getKey(), cleanValues); // 将过滤后的值存入新的映射
        }
        return map;
    }

    // 使用Jsoup进行XSS过滤的私有方法
    private String clean(String input) {
        if (input == null) {
            return null; // 如果输入为空，直接返回null
        }
        // 使用Jsoup的clean方法对输入内容进行XSS过滤
        return Jsoup.clean(input, "", safelist, outputSettings);
    }
}